package com.bensonbasement.snorflux.client.states;

import java.awt.event.KeyEvent;

import com.bensonbasement.snorflux.client.SnorfluxClient;
import com.bensonbasement.snorflux.client.SnorfluxClient.ClientState;
import com.bensonbasement.snorflux.messages.fromclient.ChatMessage;
import com.bensonbasement.snorflux.messages.fromserver.ChatCastMessage;
import com.bensonbasement.snorflux.messages.fromserver.JoinedMessage;
import com.bensonbasement.snorflux.messages.fromserver.NewPlayerMessage;
import com.bensonbasement.snorflux.messages.fromserver.PlayerInfo;
import com.bensonbasement.snorflux.messages.fromserver.PlayerStatus;
import com.bensonbasement.snorflux.messages.fromserver.PlayerStatusChangeMessage;
import com.bensonbasement.snorflux.messages.fromserver.ServerInfoMessage;
import com.bensonbasement.snorflux.messages.fromserver.ServerTimeMessage;

public abstract class ConnectedState extends ClientState {
	
	public ConnectedState(SnorfluxClient client) {
		super(client);
	}
	
	@Override
	public void initialize() {
		super.initialize();
		getChatPanel().setEnabled(true);
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			// Switch focus to chat bar.
			getChatPanel().focusChatTextField();
		}
	}
	
	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void handleTextEntered(String text) {
		ChatMessage message = new ChatMessage(text);
		sendMessage(message);
	}
	
	@Override
	public void handleTextCanceled() {
		client.focusMapPanel();
	}
	
	@Override
	public void handleConnected(JoinedMessage message) {
		throw new RuntimeException("Already connected!");
	}
	
	@Override
	public void handleDisconnected() {
		changeState(new DisconnectedState(client));
	}
	
	@Override
	public final void handleServerTimeMessage(ServerTimeMessage message) {
		if (message instanceof ChatCastMessage) {
			handleChatCastMessage((ChatCastMessage)message);
		}
		else if (message instanceof ServerInfoMessage) {
			handleServerInfoMessage((ServerInfoMessage) message);
		}
		else if (message instanceof NewPlayerMessage) {
			handleNewPlayerMessage((NewPlayerMessage)message);
		}
//		else if (message instanceof PlayerQuitMessage) {
//			handlePlayerQuitMessage((PlayerQuitMessage)message);
//		}
		else if (message instanceof PlayerStatusChangeMessage) {
			handlePlayerStatusChangeMessage((PlayerStatusChangeMessage)message);
		}
		else {
			throw new RuntimeException("Unknown message type: "+message.getClass().getCanonicalName());
		}
	}
	
	public final void handleChatCastMessage(ChatCastMessage message) {
		getChatPanel().postMessage(message.getFromPlayer()+": "+message.getChatText());
	}
	
	public final void handleServerInfoMessage(ServerInfoMessage message) {
		getChatPanel().postMessage(message.getMessageText());
	}
	
	public final void handleNewPlayerMessage(NewPlayerMessage message) {
		getChatPanel().postMessage(message.getNewPlayerName()+" joined the game.");
		PlayerInfo player = new PlayerInfo(message.getNewPlayerName(),PlayerStatus.CONNECTED);
		getPlayerListModel().addInfo(player);
	}
	
//	public final void handlePlayerQuitMessage(PlayerQuitMessage message) {
//		getChatPanel().postMessage(message.getPlayerName()+" disconnected.");
//		getPlayerListModel().removeElement(message.getPlayerName());
//	}
	
	public final void handlePlayerStatusChangeMessage(PlayerStatusChangeMessage message) {
		if (message.getNewStatus() == PlayerStatus.QUIT) {
			getPlayerListModel().removeInfo(message.getPlayerName());
		}
		else {
			getPlayerListModel().updateInfo(message.getPlayerName(),message.getNewStatus());
		}
	}
}
